import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.lang.StringBuilder
import java.nio.file.Files

class FileManager(private val callBack:ICallBack): ICommondListener {
    //实时记录当前的位置
    private var currentPath = "C:/Users/93205/Desktop/code"

    //获取当前目录名称 C:  Users 93205 Desktop
    fun currentDirectoryName():String{
        return currentPath.split("/").last()
    }

    override fun listFile(isDetail: Boolean) {
        val contents = arrayListOf<String>()
        //jack                               203.MB
        //获取当前路径file对象
        val file = File(currentPath)
        //获取所有内容的File对象
        file.listFiles().forEach {
            //将文件信息添加到contents数组中
            val sb = StringBuilder()
            val str = if (isDetail) {
                for (i in 0..(50 - it.name.charCount())) {
                    sb.append("-")
                }
                it.name + sb.toString() + it.lengthString()
            }
            else {
                it.name
            }

            contents.add(str)
        }

        //回调拿去显示
        callBack.showInfo(contents, null)
    }

    override fun showCurrentPath() {
        callBack.showInfo(null,currentPath)
    }

    // mkdir /zilai
    // mkdir d1/d2/d3
    // C:/Users/93205/Desktop/code/zilai
    override fun createDirectory(child: String) {
        //获得完整路径
        val file = fileForPath(child)
        //如果路径存在 直接结束
        if (file.exists()) return
        //创建目录
        file.mkdirs()
    }

    //C:/Users/93205/Desktop/code
    //C:/Users/93205/Desktop
    override fun returnParent() {
        currentPath.lastIndexOf("/").also {
            currentPath = currentPath.substring(0,it)
        }
    }

    //code
    //cd java
    //java
    //cd ..
    //code
    override fun changeDirectoryTo(child: String) {
        //判断是不是返回上一个目录
        if (child == ".."){
            returnParent()
            return
        }
        //进入这个目录
        val file = fileForPath(child)
        //判断路径是否正确
        if (!file.exists()){
            callBack.showInfo(null,"路径不正确")
            return
        }
        //code
        //cd java
        //C:/Users/93205/Desktop/code/java
        if (file.isDirectory){
            //进入这个目录
            currentPath = filePath(child)
        }else{
            //不是目录
            callBack.showInfo(null,"$currentPath 是一个文件")
        }
    }

    override fun delete(child: String) {
        val file = fileForPath(child)
        if (!file.exists()) {
            callBack.showInfo(null,"文件不存在")
            return
        }

        deleteFile(file)
    }

    /**
     * cp 2.txt java
     * cp kotlin java
     * cp 2.txt java
     * 只能将文件或者目录 copy 到目录里面去 而且目录需要存在
     */
    override fun copy(src: String, dest: String) {
        val destFile = fileForPath(dest)
        //判断src是否存在
        val srcFile = fileForPath(src)
        if (!srcFile.exists()) return

        if (destFile.exists() && destFile.isDirectory){
            copyFile(src,dest)
        }
    }

    /**
     * mv 2.txt java
     */
    override fun move(src: String, dest: String) {
        copyFile(src, dest)
        delete(src)
    }

    /**
     * C:/Users/93205/Desktop/code/1.txt
     * C:/Users/93205/Desktop/code/2.txt
     */
    override fun rename(old: String, new: String) {
        val oldFile = fileForPath(old)
        if (!oldFile.exists()) {
            callBack.showInfo(null, "$old 文件不存在")
            return
        }

        val newFile = fileForPath(new)
        oldFile.renameTo(newFile)

    }

    override fun createFile(child: String) {
        val file = fileForPath(child)
        if (file.exists()) {
            callBack.showInfo(null, "$child 文件已经存在")
            return
        }

        file.createNewFile()
        callBack.showInfo(null, "$child 文件创建成功")
    }

    override fun readData(child: String) {
        val file = fileForPath(child)
        if (!file.exists()) {
            callBack.showInfo(null, "$child 文件不存在")
            return
        }

        //读取文件的所有内容
        callBack.showInfo(null, file.readText())
    }

    // 1.txt
    // /1.txt
    // C:/Users/93205/Desktop/code/1.txt
    private fun fileForPath(child: String): File {
        //判断是不是已经存在路径的连接符 /
        return File(filePath(child))
    }

    private fun filePath(child: String): String{
        return if (child.startsWith("/"))
            "$currentPath$child"
        else
            "$currentPath/$child"
    }

    private fun deleteFile(file:File){
        //如果是文件就直接删掉
        if (file.isFile) {
            file.delete()
            return
        }

        //获取目录的内容
        //b.txt
        var childFiles = file.listFiles()

        //是一个目录 而且里面有内容
        //遍历我所有的子文件 继续调用deleteFile
        childFiles.forEach {
            deleteFile(it)
        }

        //注意清空数组
        //由于数组类型是普通数组，没办法删除，所以重新获取当前目录下的内容
        childFiles = file.listFiles()

        //如果当前目录为空 就删除当前所在的目录
        if (childFiles.isEmpty()) {
            file.delete()
        }
    }

    private fun copyFile(src: String, dest: String){
        //如果src是文件 直接copy
        //C:/Users/93205/Desktop/code/java
        //C:/Users/93205/Desktop/code/java/2.txt
        //C:/Users/93205/Desktop/code/2.txt
        val srcFile = fileForPath(src)
        if (srcFile.isFile){
            //获取目标路径
            val destFilePath = filePath(dest) + "/$src"
            //得到对应的file
            FileInputStream(srcFile).use { fis ->
                FileOutputStream(destFilePath).use { fos ->
                    val buffer = ByteArray(1024)
                    var len = 0
                    while (true){
                        len = fis.read(buffer,0,1024)
                        if (len == -1) break
                        fos.write(buffer,0,len)
                        fos.flush()
                    }
                }
            }
        }else {
            //如果src是目录 递归copy
            //java src  f1.jpg
            //     2.txt
            //kotlin java 2.txt
            //            src  f1.jpg
            //C:/Users/93205/Desktop/code/java/2.txt
            //C:/Users/93205/Desktop/code/kotlin
            //C:/Users/93205/Desktop/code/kotlin/java
            //拼接目标目录里面的路径
            val destPath = filePath(dest) + "/$src"
            //创建目录
            File(destPath).mkdirs()
            //将src目录下面的所有文件一个一个cpy到des目录中
            val files = srcFile.listFiles()

            files.forEach {
                //2.txt f1.jpg
                //java
                copyFile(it.name,"$dest/$src")
            }
        }
    }
}












